# -*- coding: utf-8 -*-
import copy
import shelve
import codecs


import pystore.core.framework.os2 as os2

#--- 
 
def transaction(method):
  """ 
     decorator ,
     使用@transaction描述一个类方法，此方法在执行时将进入事务状态,
     即：执行中如果有抛出异常，将恢复到未执行之前的状态。
     
  """
  def bind(object, *args, **kw):
    state = __get_state(object)
    try:
      return method(object, *args, **kw)
    except:
      __set_state(object, state)
      raise
  return bind

def __get_state(object):
  """ get the object state """
  return copy.deepcopy(object.__dict__)

def __set_state(object, state):
  """ restore the objet """
  object.__dict__.clear()
  object.__dict__.update(state)


#---

def walkFunc(nodeChildrenFunc):
    ''' 
    walkFunc(func getChildrenFunc) -> func
    
    返回一个walk函数,可以用作遍历某个树类型节点
    args:
      getChildrenFunc : 用来从节点获取其子节点迭代器
        getChildrenFunc(object node) -> iter
    return :
      walk(object node,func walkFunc,bool fromTopToBottom=True)
      walk args:
        node 遍历此节点和所有子节点
        walkFunc : walkFunc(object node ,int level) 
        fromTopToBottom : 默认从上到下遍历,也就是从根节点到叶子节点
          
    '''
    def walk(node,walkFunc,fromTopToBottom=True):
        def walkChildren(node,level):
            if fromTopToBottom:
                walkFunc(node,level)
            for child in nodeChildrenFunc(node):
                walkChildren(child,level+1)
            if not fromTopToBottom:
                walkFunc(node,level)
        walkChildren(node,0)
    return walk

#---
def writeXml(dom,filePath,coding = 'utf-8'):
    '''把dom数据以某种编码写入文件,默认为utf8'''
    os2.makeFileDirs(filePath)
    f=file(filePath, 'wb+')
    writer = codecs.lookup(coding)[3](f)
    dom.writexml(writer,encoding=coding)
    writer.close()